package br.ufal.tci.nexos.arcolive.tests;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;

import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.Control;
import javax.media.DataSink;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoDataSinkException;
import javax.media.NoProcessorException;
import javax.media.NotRealizedError;
import javax.media.Processor;
import javax.media.control.BufferControl;
import javax.media.control.FormatControl;
import javax.media.control.TrackControl;
import javax.media.format.AudioFormat;
import javax.media.protocol.DataSource;

import jmapps.util.StateHelper;

public class CaptureAudio {

	private DataSource ds = null;
	
	public CaptureAudio() {
	
		Processor processor = null;
		CaptureDeviceInfo di = null;
		StateHelper sh = null;
		
		
		Vector deviceList = CaptureDeviceManager.getDeviceList(new AudioFormat(AudioFormat.LINEAR));
		Hashtable allDevice = new Hashtable();
		for (int i = 0;i<deviceList.size() ;i++ )
		{
			di=(CaptureDeviceInfo)deviceList.elementAt(i);
			allDevice.put(di.getName(),di);
		}
		if (allDevice.isEmpty())
		{
			System.exit(-1);
		}
		else if(allDevice.containsKey("DirectSoundCapture"))
		{
			di = (CaptureDeviceInfo)allDevice.get("DirectSoundCapture");
		}
			else
			{
				di = (CaptureDeviceInfo)deviceList.firstElement();
			}
		if (di==null)
		{
			System.out.println("No Capture Devices");
			System.exit(1);
		}
		try
		{
			processor=Manager.createProcessor(di.getLocator());
			sh=new StateHelper(processor);
			processor.configure();
		}
		catch(IOException ioe)
		{
		ioe.printStackTrace();
		}
		catch(NoProcessorException npe)
		{
		npe.printStackTrace();
		}
	
		if(!sh.configure(10000))
		{
			try
			{
			throw new Exception("Audio Device failure");
			}
			catch(Exception e)
			{
			e.printStackTrace();
			}
		}
	
	//	Encoding Audio To GSM Codec Starts Here
	
		TrackControl track[] = processor.getTrackControls();
		boolean encodingOk = false;
	
	//	 Go through the tracks and try to program one of them to
	//	 output gsm data.
	
		for (int i = 0; i < track.length; i++)
		{
			if (!encodingOk && track[i] instanceof FormatControl)
			{
				if (((FormatControl)track[i]).setFormat( new AudioFormat(AudioFormat.GSM_RTP,8000,8,1)) == null)
				{
				track[i].setEnabled(false);
				}
				else
				{
					encodingOk = true;
					Format format =track[i].getFormat();
					System.out.println("****Encoding TakesPlace****");
					System.out.println("DataSourceEncodedTo:"+format.getEncoding());
					System.out.println("****Encoding Completed****");
				}
			}
			else
			{
			//	 we could not set this track to gsm, so disable it
				track[i].setEnabled(false);
		
			}
		}
		if(!sh.realize(10000))
			{
			try
			{
				throw new Exception("Audio Device failure");
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		try
		{
			ds=processor.getDataOutput();
			try {
				DataSink dsink = Manager.createDataSink(ds, new MediaLocator("file:/c:/teste.mov"));
				sh.playToEndOfMedia(5000);
				sh.close();
				dsink.close();
			} catch (NoDataSinkException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Control c = (Control)ds.getControl ("javax.media.control.BufferControl");
			if (c != null)
		//	In place of captureBufSize u can send any int value
			((BufferControl)c).setBufferLength(1000);
	
		}
		catch(NotRealizedError nr)
		{
			nr.printStackTrace();
		}
	}
	
	public DataSource getDataSource() {
		return this.ds;
	}
	
	public static void main(String[] args) {
		CaptureAudio ca = new CaptureAudio();
//		LVSRecordMedia rm = new LVSRecordMedia();
//		rm.setTarget("file:/c:/teste.mov");
//		try {
//			rm.createRecordMedia(ca.getDataSource());
//			rm.write(5000);
//			rm.closeWriter();
//		} catch (NoProcessorException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (CannotRealizeException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (NoDataSinkException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}
}
